package main

import (
	"encoding/gob"
	"github.com/gin-contrib/cors"
	"github.com/gin-contrib/sessions"
	"github.com/gin-contrib/sessions/cookie"
	"github.com/gin-gonic/gin"
	"github.com/gomodule/redigo/redis"
	"net/url"
	"smartLearn/conf"
	"smartLearn/ctrl/exam"
	"smartLearn/ctrl/image"
	"smartLearn/ctrl/knowledge"
	"smartLearn/ctrl/level"
	"smartLearn/ctrl/qtype"
	"smartLearn/ctrl/question"
	"smartLearn/ctrl/source"
	"smartLearn/ctrl/subject"
	"smartLearn/ctrl/user"
	"smartLearn/models"
	"smartLearn/modules/cache"
	"smartLearn/modules/response"

	"strings"
)

func main() {
	Load()                     //载入配置
	gob.Register(models.UserSessionInfo{})
	gin.SetMode(gin.DebugMode) //开发环境
	//gin.SetMode(gin.ReleaseMode) //线上环境
	r := gin.Default()







	/*store, err := redis.NewStoreWithPool(cache.RedisClient, []byte("secret"))
	/*store, err := redis.NewStore(10,"tcp","localhost:6379","", []byte("secret"))
	store.Options(sessions.Options{
		MaxAge: int(30*time.Minute),
		Path:"/",
	})
	if err!=nil {
		log.Fatal("Redis 没有启动")
		return
	}
	*/
	store:=cookie.NewStore([]byte("secrect"))

	r.Use(sessions.Sessions("gosession", store))


	r.Use(cors.New(GetCorsConfig()))//跨域
	//r.Use(cors.Default())//默认跨域
	r.Use(Auth())
	r.POST("/api/user/register",user.Create)
	r.GET("/api/user/checkname",user.IsExist)

	r.POST("/api/user/login",user.Login)
	r.POST("/api/user/logout",user.Logout)


	r.GET("/api/role/listall",user.GetRollAll)
	r.GET("/api/user/info",user.GetMenu)

	r.GET("/api/subject/listall",subject.GetSubjectAll)
	r.POST("/api/subject/add",subject.Add)
	r.POST("/api/subject/update",subject.Update)
	r.DELETE("/api/subject/delete",subject.Delete)

	r.GET("/api/type/listall",qtype.GetTypeAll)
	r.GET("/api/type/list",qtype.GetTypeBySubjectId)
	r.POST("/api/type/add",qtype.Add)
	r.GET("/api/type/subjectlist",qtype.GetSubjectListByTypeId)

	r.POST("/api/type/update",qtype.Update)
	r.DELETE("/api/type/delete",qtype.Delete)



	r.GET("/api/level/listall",level.GetLevelAll)
	r.POST("/api/level/add",level.Add)
	r.POST("/api/level/update",level.Update)
	r.DELETE("/api/level/delete",level.Delete)


	r.GET("api/source/list",source.GetList)
	r.GET("api/source/get",source.GetById)
	r.POST("/api/source/add",source.Add)
	r.POST("/api/source/update",source.Update)
	r.DELETE("/api/source/delete",source.Delete)


	r.GET("api/knowledge/list",knowledge.GetList)
	r.GET("api/knowledge/get",knowledge.GetById)
	r.POST("/api/knowledge/add",knowledge.Add)
	r.POST("/api/knowledge/update",knowledge.Update)
	r.DELETE("/api/knowledge/delete",knowledge.Delete)

	r.POST("/api/question/add",question.Add)
	r.GET("/api/question/list",question.List)
	r.GET("/api/question/get/:id",question.GetById)
	r.POST("/api/question/update/:id",question.Update)
	r.DELETE("/api/question/delete/:id",question.Delete)
	r.POST("/api/question/updateVerifyStatus",question.UpdateVerifiyStatus)
	r.POST("/api/question/updateValidStatus",question.UpdateValidStatus)
	r.POST("/api/question/updateTestStatus",question.UpdateTestStatus)
	r.GET("/api/question/listTestStatus",question.ListTestStatus)
	r.GET("/api/question/listQuestions",question.ListQuestions)
	r.GET("/api/question/listAnswers",question.ListAnswers)

	r.POST("api/user/action/updatelibrary",user.UpdateLibrary)


	r.POST("/api/exam/removequestion",exam.RemoveQuestion)
	r.POST("/api/exam/add",exam.Add)
	r.GET("/api/exam/list",exam.List)
	r.GET("/api/exam/listQuestion",exam.ListQuestion)
	r.POST("/api/exam/update/:id",exam.Update)
	r.DELETE("/api/exam/delete/:id",exam.Delete)

	r.GET("/img/:id", image.ShowImage)
	r.POST("/api/img/add", image.AddImage)
	r.POST("/api/img/deleteuseless", image.DeleteUseless)

	r.GET("/ping", func(c *gin.Context) {
		c.JSON(200, gin.H{
			"message": "pong",
		})
	})
	r.GET("/showimg", func(c *gin.Context) {
		c.JSON(200, gin.H{
			"message": "pong",
		})
	})

	//r.Run(":7890")
	r.RunTLS(":7890","./ca/server.crt","./ca/server.key")
}
func GetCorsConfig() cors.Config {
	config := cors.DefaultConfig()
	//config.AllowOrigins = []string{"*","https://zyinfo.com","http://localhost:9529","http://localhost:9528","http://localhost:9527","http://localhost：7890","http://localhost：8080"}
	config.AllowOrigins = []string{"*"}

	config.AllowMethods = []string{"POST", "GET", "OPTIONS", "PUT", "DELETE"}
	config.AllowCredentials = true
	config.AllowHeaders = []string{"x-requested-with", "Content-Type", "AccessToken", "X-CSRF-Token","X-Token", "Authorization","token"}

	return config
}

func Load() {
	c := conf.Config{}
	/*
	c.Routes=[]string{"/ping","/img","/api/img/add","/api/user/register","/api/role/listall","/api/user/checkname","/api/user/login",
		"/api/subject/listall","/api/type/listall","/api/level/listall","/api/user/info"}*/
	//不需要登录就能够访问的URL
	c.Routes=[]string{"/ping","/api/user/login","/api/user/checkname","/api/user/register","/api/role/listall","/img/"}
	conf.Set(c)
}

//查找某值是否在数组中
func IsStartPath(v string, m *[]string) bool {
	for _, value := range *m {
		if strings.HasPrefix(v,  value) == true{
			return true
		}
	}
	return false
}
func Auth() gin.HandlerFunc{
	return func(c *gin.Context) {
		u,err:= url.Parse(c.Request.RequestURI)
		if err != nil {
			panic(err)
		}
		if IsStartPath(u.Path,&conf.Cfg.Routes) {
			//请求的Request路径是否在路由列表里，如果是的话继续,不用鉴权
			c.Next()
			return
		}



		rc:=cache.RedisClient.Get()
		defer rc.Close()

		token:=c.GetHeader("authorization")
		uid,err:= redis.Int(rc.Do("get",token))


		if uid==0 {
			c.Abort()
			response.ShowError(c,"nologin")
			return
		}

		users := models.SystemUser{Id:uid}
		has:=users.GetRow()
		if !has {
			c.Abort()
			response.ShowError(c,"user_error")
			return
		}
		//到下一个链接
		c.Next()
		return


	}
}

